package com.controller;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;

import org.apache.log4j.Logger;
import org.primefaces.event.SelectEvent;
import org.springframework.web.jsf.FacesContextUtils;

import com.builder.ClienteBuilder;
import com.builder.FamiliaBuilder;
import com.builder.OrdenDeCompraBuilder;
import com.builder.OrdenDeCompraDetalleBuilder;
import com.builder.ProductoBuilder;
import com.dao.BaseModelDAO;
import com.model.Familia;
import com.model.OrdenDeCompra;
import com.model.Producto;
import com.query.ReporteRentabilidadQuery;
import com.support.ReporteRentabilidadSupport;
import com.view.FamiliaView;
import com.view.ProductoView;

@ManagedBean
@ViewScoped
@SuppressWarnings("serial")
public class ReporteRentabilidadController extends
		PaginableController<OrdenDeCompra> {

	private Logger log = Logger.getLogger(ReporteRentabilidadController.class);
	private OrdenDeCompra ordenDeCompra;
	private ReporteRentabilidadQuery query;

	private List<FamiliaView> listaDeFamilia;

	private List<ReporteRentabilidadSupport> listaReporteRentabilidad;

	private BigDecimal rentabilidadTotal;

	private BaseModelDAO<OrdenDeCompra> daoOrdenDeCompra;
	private BaseModelDAO<Producto> daoProducto;
	private BaseModelDAO<Familia> daoFamilia;

	private ProductoView productoView;

	@ManagedProperty("#{ordenDeCompraBuilder}")
	private OrdenDeCompraBuilder ordenDeCompraBuilder;

	@ManagedProperty("#{ordenDeCompraDetalleBuilder}")
	private OrdenDeCompraDetalleBuilder ordenDeCompraDetalleBuilder;

	@ManagedProperty("#{productoBuilder}")
	private ProductoBuilder productoBuilder;

	@ManagedProperty("#{clienteBuilder}")
	private ClienteBuilder clienteBuilder;

	@ManagedProperty("#{familiaBuilder}")
	private FamiliaBuilder familiaBuilder;

	@SuppressWarnings("unchecked")
	public ReporteRentabilidadController() {
		try {
			daoOrdenDeCompra = (BaseModelDAO<OrdenDeCompra>) FacesContextUtils
					.getWebApplicationContext(FacesContext.getCurrentInstance())
					.getBean("ordenDeCompraDAO");

			daoProducto = (BaseModelDAO<Producto>) FacesContextUtils
					.getWebApplicationContext(FacesContext.getCurrentInstance())
					.getBean("productoDAO");

			daoFamilia = (BaseModelDAO<Familia>) FacesContextUtils
					.getWebApplicationContext(FacesContext.getCurrentInstance())
					.getBean("familiaDAO");

			query = new ReporteRentabilidadQuery();
			addEdit = false;

			rentabilidadTotal = BigDecimal.ZERO;
		} catch (Throwable e) {
			log.error(
					"Error al inicializar la clase ReporteRentabilidadController",
					e);
			FacesContext.getCurrentInstance().addMessage(
					null,
					new FacesMessage(FacesMessage.SEVERITY_ERROR,
							"Error al realizar la operacion", ""));
		}
	}

	@PostConstruct
	private void init() {

		listaDeFamilia = new ArrayList<FamiliaView>();
		listaDeFamilia.addAll(familiaBuilder.toView(daoFamilia.getList()));
	}

	@SuppressWarnings("unchecked")
	public void query(ActionEvent event) {

		if (productoView != null) {
			query.setProductoID(productoView.getId());
		} else {
			query.setProductoID(null);
		}

		List<Object[]> lista = daoOrdenDeCompra.getListObjects(query);

		listaReporteRentabilidad = new ArrayList<ReporteRentabilidadSupport>();
		rentabilidadTotal = BigDecimal.ZERO;

		for (Object[] obj : lista) {
			ReporteRentabilidadSupport support = new ReporteRentabilidadSupport();
			support.setProducto(obj[0].toString());
			support.setFamilia(obj[1].toString());
			
			if (obj[2] != null) {
				support.setUnidadMedida(obj[2].toString());
			} else {
				support.setUnidadMedida("");
			}
			
			if (obj[3] != null) {
				support.setVenta(new BigDecimal(obj[3].toString()));
			} else {
				support.setVenta(BigDecimal.ZERO);
			}
			
			if (obj[4] != null) {
				support.setCompra(new BigDecimal(obj[4].toString()));
			} else {
				support.setCompra(BigDecimal.ZERO);
			}
			
			if (obj[5] != null) {
				support.setVentaPeso(new BigDecimal(obj[5].toString()));
			} else {
				support.setVentaPeso(BigDecimal.ZERO);
			}
			
			if (obj[6] != null) {
				support.setCompraPeso(new BigDecimal(obj[6].toString()));
			} else {
				support.setCompraPeso(BigDecimal.ZERO);
			}

			// rentabilidad
			support.setRentabilidad(support.getVenta().subtract(
					support.getCompra()));

			// rentabilidad Total
			rentabilidadTotal = rentabilidadTotal
					.add(support.getRentabilidad());

			listaReporteRentabilidad.add(support);
		}

		System.out.println("trajo lo siguiente: "
				+ listaReporteRentabilidad.size());
		// loadList();
	}

	public void edit(Long id, String disabled) {
		// No se necesita para reportes
	}

	@Override
	public void add(ActionEvent event) {

		// No se necesita para reportes
	}

	@Override
	public void save(ActionEvent event) {

		// No se necesita para reportes
	}

	@Override
	public void cancel(ActionEvent event) {
		addEdit = false;
		clear();
	}

	public BaseModelDAO<OrdenDeCompra> getDao() {
		return daoOrdenDeCompra;
	}

	public void setDao(BaseModelDAO<OrdenDeCompra> dao) {
		this.daoOrdenDeCompra = dao;
	}

	public OrdenDeCompra getOrdenDeCompra() {
		return ordenDeCompra;
	}

	public void setOrdenDeCompra(OrdenDeCompra ordenDeCompra) {
		this.ordenDeCompra = ordenDeCompra;
	}

	public ProductoBuilder getProductoBuilder() {
		return productoBuilder;
	}

	public void setProductoBuilder(ProductoBuilder productoBuilder) {
		this.productoBuilder = productoBuilder;
	}

	public BaseModelDAO<Producto> getDaoProducto() {
		return daoProducto;
	}

	public void setDaoProducto(BaseModelDAO<Producto> daoProducto) {
		this.daoProducto = daoProducto;
	}

	public OrdenDeCompraBuilder getOrdenDeCompraBuilder() {
		return ordenDeCompraBuilder;
	}

	public void setOrdenDeCompraBuilder(
			OrdenDeCompraBuilder ordenDeCompraBuilder) {
		this.ordenDeCompraBuilder = ordenDeCompraBuilder;
	}

	public OrdenDeCompraDetalleBuilder getOrdenDeCompraDetalleBuilder() {
		return ordenDeCompraDetalleBuilder;
	}

	public void setOrdenDeCompraDetalleBuilder(
			OrdenDeCompraDetalleBuilder ordenDeCompraDetalleBuilder) {
		this.ordenDeCompraDetalleBuilder = ordenDeCompraDetalleBuilder;
	}

	@Override
	public void edit(ActionEvent event) {
		// TODO Auto-generated method stub

	}

	public ClienteBuilder getClienteBuilder() {
		return clienteBuilder;
	}

	public void setClienteBuilder(ClienteBuilder clienteBuilder) {
		this.clienteBuilder = clienteBuilder;
	}

	@Override
	public void delete(ActionEvent event) {
		// TODO Auto-generated method stub

	}

	public FamiliaBuilder getFamiliaBuilder() {
		return familiaBuilder;
	}

	public void setFamiliaBuilder(FamiliaBuilder familiaBuilder) {
		this.familiaBuilder = familiaBuilder;
	}

	public List<FamiliaView> getListaDeFamilia() {
		return listaDeFamilia;
	}

	public ReporteRentabilidadQuery getReporteQuery() {
		return query;
	}

	public BigDecimal getRentabilidadTotal() {
		return rentabilidadTotal;
	}

	@Override
	public void clear() {
		// TODO Auto-generated method stub

	}

	public List<ProductoView> completeProducto(String query) {
		List<ProductoView> listaProducto = null;
		try {

			List<Producto> listaProductosEntity = daoProducto.getList(query);
			if (listaProductosEntity != null && listaProductosEntity.size() > 0) {
				listaProducto = productoBuilder.toView(listaProductosEntity);
			}

		} catch (Throwable e) {
			log.error("Error en le metodo completeProducto: ", e);
			FacesContext.getCurrentInstance().addMessage(
					null,
					new FacesMessage(FacesMessage.SEVERITY_ERROR,
							"Error al realizar la operacion", ""));
		}
		return listaProducto;
	}

	public boolean isProductoSelected() {
		return (productoView != null && productoView.getId() != null);
	}

	public void deselecionarProducto(ActionEvent event) {
		productoView = null;
	}

	public void productoSelectChange(SelectEvent event) {
		productoView = ((ProductoView) event.getObject());
		System.out.println("se eligio una un producto "
				+ productoView.getDetalle());
	}

	public ProductoView getProductoView() {
		return productoView;
	}

	public void setProductoView(ProductoView productoView) {
		this.productoView = productoView;
	}

	public List<ReporteRentabilidadSupport> getListaReporteRentabilidad() {
		return listaReporteRentabilidad;
	}

}
